﻿//*** Guidance generated code ***//
using System;
using System.Collections.Generic;
using System.Linq;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using ProjectBase.Core;
using ProjectBase.Mvc;

using $prjsn$.Common;
using $prjsn$.Common.Business.Services;
using $prjsn$.Entity.Services;

namespace $safeprojectname$.Services
{
    /// <summary>
    /// Basic tests fro User entity
    /// </summary>
    [TestClass]
    public class UserTest : EntityTestBase<IUserFacade>
    {
        /// <summary>
        /// RE-use. Let's this method converts any entity into valid one
        /// (for all tests do it ones - here)
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        protected virtual User MakeItValid(User entity)
        {
            Messages.Clear();
            entity = entity ?? Facade.CreateNew();

            entity.Login = Guid.NewGuid().ToString();
            entity.FirstName = "First";
            entity.LastName = "Last";

            return entity;
        }

        #region Get
        /// <summary>
        /// Try to test your filtering criteria as much as possible.
        /// </summary>
        [TestMethod]
        public void Find()
        {
            var filter = new UserFilter
                             {
                                 LoginExact = "TestLogIN",
                                 Login = "*loGI*",
                                 TakeRows = 1,
                             };
            var result = Facade.Find(filter);
            Assert.IsTrue(result.Count() > 0, " there must be User entity which meets provided filtering criteria ");
        }

        [TestMethod]
        public void GetByLogin()
        {
            var result = Facade.GetByLogin("TestlogIN");
            Assert.IsTrue(result.Is());
            Assert.IsTrue(result.Login.IsEqual("TestLoGin"));
        }
        #endregion Get

        #region Set
        /// <summary>
        /// Firstly tries to store 'business-point-of-view' incorrect entity - to get an Error Message.
        /// Secondly MakesItValid to assure the this will be stored
        /// </summary>
        [TestMethod]
        public void NewUser()
        {
            Messages.Clear();
            //   I. Ask Facade to get new (pre-filled but not valid - e.g. Login is missing)
            var entity = Facade.CreateNew();

            entity.Login = null; // to fail

            //  II. Assure that Facade won't allow to store this
            entity = Facade.Add(entity);
            Assert.IsTrue(entity.IsTransient());
            Assert.IsTrue(Messages.ContainsError());


            // III. Make entity valid
            Messages.Clear();
            entity = MakeItValid(entity);

            //  IV. Assure that valid will be stored
            entity = Facade.Add(entity);

            Assert.IsFalse(Messages.ContainsError(), Messages.GetErrorMessage());
            Assert.IsFalse(entity.IsTransient(), " MakeItValid was called, so 'User' Entity must be storable and NOT Transient now");
        }

        /// <summary>
        /// Tries to store similar entity (e.g. code property)
        /// to get the Error Message 'AlreadyExists'
        /// </summary>
        [TestMethod]
        public void AlreadyExistsUserCheck()
        {
            //   I. Get existing entity from DB
            var oldEntity = Facade.Find(new UserFilter { TakeRows = 1 }).SingleOrDefault();
            if (oldEntity.IsNull())
            {
                Assert.Inconclusive(" To run this test there must be at least one 'User' entity in DB ");
                return;
            }

            //  II. Create new transient 'VALID' entity
            var entity = MakeItValid(null);

            // III. Set the property to get similar entities, which should be prohibited
            entity.Login = oldEntity.Login;

            //  IV. Call Facade to store new one
            Messages.Clear();
            entity = Facade.Add(entity);

            //   V. Facade must stop storing this
            Assert.IsTrue(entity.IsTransient());
            Assert.IsTrue(Messages.ContainsError());

        }

        /// <summary>
        /// Test that UPDATE checks are working
        /// </summary>
        [TestMethod]
        public void UpdateUser()
        {
            // I. get existing
            var entity = Facade.Find(new UserFilter { TakeRows = 1 }).SingleOrDefault();
            if (entity.IsNull())
            {
                Assert.Inconclusive(" there is no Entity record in DB Storage to test update");
                return;
            }

            // II. change it to get error
            Messages.Clear();
            entity.Login = null;

            // TODO change to get failures
            entity = Facade.Update(entity);

            // III. check there are errors
            Assert.IsTrue(Messages.ContainsError(), " There must be generated Error messages for not completely provided entity");

            Messages.Clear();
            // IV. repair it and check it will be stored

            entity = MakeItValid(entity);

            Facade.Update(entity);
            // V. now it must be OK
            Assert.IsFalse(Messages.ContainsError(), Messages.GetErrorMessage());
        }

        /// <summary>
        /// Essential TEST !!!!!
        /// !!!!!!!!!!!!!!!!!!!!
        ///
        /// Assure there, that your entity cannot be delted, when is used by another entity!
        /// It will help you! soon, you'll see...
        /// </summary>
        //[TestMethod]
        public void DeleteUser()
        {
            Assert.Inconclusive("Not implemented yet");
            Messages.Clear();

            //// I. call some holder to get 'InUse' entity
            //IOtherEntityFacade tradeFacade = FacadeFactory.CreateFacade<IOtherEntityFacade>();
            //var holder = tradeFacade.Find(new OtherEntitySearch() { TakeRows = 1 }).SingleOrDefault();
            //Assert.IsTrue(holder.Is(), " There must be at least some 'OtherEntity' entity in DB");

            //// II. now get this entity using Facade and its.ID
            //var entity = Facade.GetById(holder.User.ID);

            //// III. this must fail
            //Facade.Delete(entity);

            Assert.IsTrue(Messages.ContainsError(), " Entity cannot be delted, Error missing");
        }
        #endregion Set

        #region Additional test attributes
        // constructor
        [ClassInitialize]
        public static void MyClassInitialize(TestContext testContext) { }

        [ClassCleanup]
        public static void MyClassCleanup() { }

        [TestInitialize]
        public override void MyTestInitialize() { base.MyTestInitialize(); }

        [TestCleanup]
        public override void MyTestCleanup() { base.MyTestCleanup(); }
        #endregion Additional test attributes
    }
}